/* ========================================================================= */
/* ------------------------------------------------------------------------- */
/*!
  \file			PrpAgreg.h
  \date			June 2011
  \author		TNick

  \brief		Contains the definition for PrpAgreg class


 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @n
 Please read ReadMe.txt and Licence.txt in root folder @n
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @n

*/
/* ------------------------------------------------------------------------- */
/* ========================================================================= */
#ifndef __CC_PRPAGREG_INC__
#define __CC_PRPAGREG_INC__
//
//
//
//
/*  INCLUDES    ------------------------------------------------------------ */

#include	<QtGlobal>

/*  INCLUDES    ============================================================ */
//
//
//
//
/*  CLASS    --------------------------------------------------------------- */

/// class
/**
*	This class handles consistent properties management inside entire
*	application. Each object exposing a property to the user shall asign a code
*	to that property. Each object that makes use of the system shall use two
*	functions:
*	- one that is capable to scan a list of properties and to extract
*	meaningful information
*	- one that inserts the properties of that particular object in a list
*
*	The unique code consists of a number of fields that help in management
*	process. The fields are:
*	- Advanced (Bit 31): a property may be either marked advanced or not
*	- Group (Bits 30 - 27): 16 major groups, among which first one is General
*	(holding most common properties); visually, these appear on diffrent tabs.
*	- subgroup (Bits 26 - 22): 31 subtypes in each group; visually, they
*	are headers in a tab
*	- source (Bits 21 - 15): 128 possible sources; visually, this has no effect;
*	this is done only to allow to each item it's own count.
*	- property storage type: (Bits 14 - 8): 128 storage types
*	- property id: (Bits 7 - 0): 256 unique properties
*
*	Whenever a new property needs to be defined, the list of existing
*	properties needs to be checked. If the property is already defined
*	elsewhere, that definition is used.
*
*	For the manager / viewer the ID is a simple number when it comes to
*	comparing two properties. The id is splitted in 3 parts and, according to
*	the values that are found, a place is assigned in visual representation.
*
*	As this class manages global scope of this system, it is also responsable
*	for providing the strings that identify groups, subgroups and global items.
*	For items that make use of the source fiels, that particular item
*	is responsable.
*
*	This class is just an fancy quint32 associuated with a vtable.
*/
class PrpAgreg 		{

	//
	//
	//
	//
	/*  DEFINITIONS    ----------------------------------------------------- */
public:

	/* advanced bit	*/
#define	PAGR_ADV	0x80000000
#define PAGR_SET_ADV(trg,set)	trg = static_cast<quint32>(trg | ((set & 0x1) << 31))
#define PAGR_GET_ADV(val)	((val & PAGR_ADV)   >> 31)
#define PAGE_IS_ADV(val)	(PAGR_GET_ADV(val) == 1)

	/* group mask	*/
#define PARG_GRP	(0xF << 27)
#define PAGR_SET_GRP(trg,grp)	trg = static_cast<quint32>(trg | ((grp & 0xF) << 27))
#define PAGR_GET_GRP(val)	((val & PARG_GRP)   >> 27)

	/* subgroup mask	*/
#define PARG_SGR	(0x1F << 22)
#define PAGR_SET_SGR(trg,sgr)	trg = static_cast<quint32>(trg | ((sgr & 0x1F) << 22))
#define PAGR_GET_SGR(val)	((val & PARG_SGR)   >> 22)

	/* source mask	*/
#define PARG_SRC	(0x7F << 15)
#define PAGR_SET_SRC(trg,src)	trg = static_cast<quint32>(trg | ((src & 0x7F) << 15))
#define PAGR_GET_SRC(val)	((val & PARG_SRC)   >> 15)

	/* storage type mask	*/
#define PARG_ST		(0x7F << 8) )
#define PAGR_SET_ST(trg,srcid)	trg = static_cast<quint32>(trg | ((srcid & 0x7F) << 8))
#define PAGR_GET_ST(val)	((val & PARG_ID)      >> 8)

	/* ID mask	*/
#define PARG_ID		(0xFF << 0)
#define PAGR_SET_ID(trg,srcid)	trg = static_cast<quint32>(trg | ((srcid & 0xFF) << 0))
#define PAGR_GET_ID(val)	((val & PARG_ID)      >> 0)

	/* SourceId group */
#define PARG_SRCID	(PARG_SRC | PARG_ST | PARG_ID)
#define PAGR_SET_SRCID(trg,srcid)	trg = static_cast<quint32>(trg | (srcid & PARG_SRCID))
#define PAGR_GET_SRCID(val)		(val & PARG_SRCID)

	/// creates a single value from all provided informations)
#define PARG(trg,a,grp,sgr,src,strg,srcid) \
	trg = static_cast<quint32>( \
								((a & 0x1) << 31) | \
								((grp & 0xF) << 27) | \
								((sgr & 0x1F) << 22) | \
								((src & 0x7F) << 15) | \
								((strg & 0x7F) << 8) | \
								((srcid & 0xFF) << 0))


			/// describes all possible groups
			enum	GRP
		{
			GENERAL = 0,/**< main group; most of the properties
			shall belong to this group; as the program advances, new
			groups may be defined */

			GRP_MAX		/**< for validation purposes */
		};


	/* definitions for subgroups belonging to
	all groups shall be placed here */

	/// subgroups for PrpAgreg::GENERAL group
	enum	GGENERAL
		{
			G_TOP = 0,	/**< most basic properties */

			GGEN_MAX	/**< for validation purposes */
		};

	/// groups definitions for all possible sources
	enum	SOURCE
		{
			SGEN1 = 0,	/**< generic source (and, as
			such, usable from everywhere; ID's are defined in this class */

			SMAX		/**< for validation purposes */
		};

	/// ID's for items that belong to generic source */
	enum	SGENID
		{
			GID_LAYER = 0,/**< layer name */

			GID_MAX		/**< for validation purposes */
		};

	/// ID's for items that belong to generic source */
	enum	STORAGE
		{
			ST_INT = 0,	/**< integer */
			ST_STR,		/**< string */
			ST_BOOL,	/**< boolean */

			ST_MAX		/**< for validation purposes */
		};




	/*  DEFINITIONS    ===================================================== */
	//
	//
	//
	//
	/*  DATA    ------------------------------------------------------------ */

private:

	/// a code describing this class
	quint32		id;

	/*  DATA    ============================================================ */
	//
	//
	//
	//
	/*  FUNCTIONS    ------------------------------------------------------- */

public:

	/// default constructor;
	/**
	*	simply sets the internal id to an arbitrary value
	*/
	PrpAgreg		(void) { id = 0; }
	/// constructor;
	/**
	*	sets the internal id to provided value
	*/
	PrpAgreg		(quint32 init_val) { id = init_val; }
	/// constructor;
	/**
	*	sets the internal id to provided properties
	*/
	PrpAgreg		(
			bool	a_adv,
			GRP		a_grp,
			int		a_sgrp,
			SOURCE	a_src,
			STORAGE	a_strg,
			int		a_id
	){ id = 0; PARG(id, a_adv, a_grp, a_sgrp, a_src, a_strg, a_id); }



	/// destructor;
	/**
	*	there is nothing to do, as we're not allocating anything
	*/
	virtual			~PrpAgreg		(void) {}


	/// short description
	/**
	*	extended description
	*
	*	@return		description for return
	*/
	int					Sample_Function		(
			int					arg1,		/**< desacription */
			double				arg2		/**< desacription */
			);

	/// tell if this property is an advanced one
	inline bool		isAdvanced		(void) const
		{ return PAGE_IS_ADV(id); }
	/// make this property advanced or not
	inline void		advanced		(bool bv)
		{ PAGR_SET_ADV(id,(bv ? 1 : 0)); }


	/// get the group index
	inline	GRP		group			(void) const
		{ return (GRP)PAGE_IS_ADV(id); }
	/// set the group index
	inline	void	setGroup		(GRP nv)
		{ PAGR_SET_GRP(id,nv); }


	/// get the subgroup index
	inline	int		subgroup		(void) const
		{ return PAGE_IS_ADV(id); }
	/// set the subgroup index
	inline	void	setSubGroup		(int nv)
		{ PAGR_SET_SGR(id,nv); }


	/// get the source index
	inline	SOURCE	source			(void) const
		{ return (SOURCE)PAGE_IS_ADV(id); }
	/// set the source index
	inline	void	setSource		(SOURCE nv)
		{ PAGR_SET_SRC(id,nv); }


	/// get the index
	inline	int		uniqIdx			(void) const
		{ return (SOURCE)PAGE_IS_ADV(id); }
	/// set the source index
	inline	void	setUniqIdx		(int nv)
		{ PAGR_SET_ID(id,nv); }

	/// get the entire id value
	inline	quint32	entireId		(void) const
		{ return id; }

	/// set the entire id value
	inline	void	setEntireId		(quint32 nv)
		{ id = nv; }




	/*  FUNCTIONS    ======================================================= */
	//
	//
	//
	//

};	/*	class PrpAgreg	*/

/*  CLASS    =============================================================== */
//
//
//
//
#endif // __CC_PRPAGREG_INC__
/* ------------------------------------------------------------------------- */
/* ========================================================================= */

